package cn.waka.sys.admin.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

import cn.waka.sys.admin.dao.INodeDao;
import cn.waka.sys.admin.object.Node;

@Service
public class NodeService {

    private static List<String> list = null;
    private INodeDao nodeDao;
    private static final String key = "_auth_all";
    private RedisService redisService;

    public List<Node> findAll() {
        return nodeDao.findAll();
    }

    public List<String> findAllURI() {

        boolean exist = redisService.exists(key);

        if (exist && list != null) {
            return list;
        } else {
            list = nodeDao.findAllURI();
            redisService.set(key, "1");
            return list;
        }
    }

    @PostConstruct
    public void init() {
        this.refreshCache();
    }

    public void refreshCache() {
        String key = "_auth_all";
        String str = redisService.get(key);
        if (str != null) {
            redisService.del(key);
            List<String> list = nodeDao.findAllURI();
            if (list != null && list.size() > 0) {
                str = JSON.toJSONString(list);
                redisService.set(key, str);
            }
        }
    }

    public int save(Node node) {
        int rs = 0;
        if (node.getId() == 0) {
            rs = nodeDao.insert(node);
        }
        return rs;
    }

    public List<Node> getSelectNode() {
        return nodeDao.getSelectNode();
    }

    public List<Node> getNodeList() {
        List<Node> list = nodeDao.getNodeList();
        Map<Integer, Node> msAll = new HashMap<Integer, Node>();
        for (Node m : list) {
            msAll.put(m.getId(), m);
        }

        for (Node n : list) {
            String key = "";
            if (n.getPid() == 0) {
                key = "" + n.getId();
            } else {
                key = n.getId() + "-" + msAll.get(n.getPid()).getKey();
            }
            msAll.get(n.getId()).setKey(key);
        }
        List<Node> ms = new ArrayList<Node>();
        for (Node m : msAll.values()) {
            if (m.getPid() == 0) {
                ms.add(m);
            } else {
                msAll.get(m.getPid()).add(m);
            }
        }

        ms = arrTree(ms);
        return ms;
    }

    private List<Node> arrTree(List<Node> list) {
        List<Node> arrlist = new ArrayList<Node>();
        for (Node m : list) {
            int k = m.getKey().split("-").length;
            String spl = StringUtils.repeat("&nbsp;&nbsp;&nbsp;├&nbsp;&nbsp;", k - 1);
            m.setKey(spl);
            arrlist.add(m);
            if (m.getChildren() != null) {
                List<Node> _arrlist = arrTree(m.getChildren());
                arrlist.addAll(_arrlist);
            }
        }

        return arrlist;
    }

    public Node getNodeById(int id) {
        return nodeDao.getNodeById(id);
    }

    public int update(Node node) {
        List<Node> nodes = nodeDao.getSelectChildren(node.getPid());
        Node pNode = nodeDao.getNodeById(node.getPid());
        if (nodes.size() <= 1 && pNode != null) {
            pNode.setId(node.getPid());
            pNode.setMenu(node.isMenu());
            nodeDao.update(pNode);
        }
        return nodeDao.update(node);
    }

    @Autowired
    public void setNodeDao(INodeDao nodeDao) {
        this.nodeDao = nodeDao;
    }

    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }

    public List<Node> getNodeTree(int roleId) {
        List<Node> list = nodeDao.getNodeTree(roleId);

        final Map<Integer, Node> msAll = new LinkedHashMap<Integer, Node>();


        Node top = new Node();
        top.setId(0);
        top.setTitle("顶级节点");
        top.setNode("顶级节点");
        top.setPid(-1);
        top.setChecked(true);
        msAll.put(0, top);
        for (Node node : list) {
            msAll.put(node.getId(), node);
        }
        List<Node> ms = new LinkedList<Node>();
        for (Node m : msAll.values()) {
            if (m.getPid() == -1) {
                ms.add(m);
            } else {
                msAll.get(m.getPid()).add(m);
            }
        }

        return ms;


    }

    public int saveNodes(String role_id, String[] nodes) {
        nodeDao.delAll(role_id);
        for (String node : nodes) {
            nodeDao.insertAuthNode(role_id, node);
        }
        return 1;
    }

}
